<template>
    <div class="device-info">
        <div class="theme-toggle">
            <button @click="toggleTheme" :class="{ 'active': currentTheme === 'light' }">
                <span>🌞</span>
            </button>
            <button @click="toggleTheme" :class="{ 'active': currentTheme === 'dark' }">
                <span>🌙</span>
            </button>
        </div>

        <h1 class="title">设备信息概览</h1>

        <div v-for="(section, sectionKey) in organizedInfo" :key="sectionKey" class="info-section">
            <h2 class="section-title">{{ formatTitle(sectionKey) }}</h2>
            <div class="info-grid">
                <template v-if="isObject(section)">
                    <div v-for="(value, key) in section" :key="key" class="info-item">
                        <label>{{ formatTitle(key) }}:</label>
                        <span>{{ formatValue(value) }}</span>
                    </div>
                </template>
                <div v-else class="info-item">
                    <span>{{ formatValue(section) }}</span>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
export default {
    data() {
        return {
            deviceInfo: {},
            organizedInfo: {},
            currentTheme: 'light'
        };
    },

    async mounted() {
        await this.initDeviceInfo();
        this.currentTheme = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
    },

    methods: {
        toggleTheme() {
            this.currentTheme = this.currentTheme === 'light' ? 'dark' : 'light';
        },

        async initDeviceInfo() {
            this.deviceInfo = await this.getDeviceInfo();
            this.organizeInfo();
        },

        async getDeviceInfo() {
            const deviceInfo = {
                userAgent: navigator.userAgent,
                platform: navigator.platform,
                language: navigator.language,
                languages: navigator.languages || [navigator.language],
                appVersion: navigator.appVersion,
                appName: navigator.appName,
                vendor: navigator.vendor,
                product: navigator.product,
                online: navigator.onLine,
                cookieEnabled: navigator.cookieEnabled,
                doNotTrack: navigator.doNotTrack,
                pdfViewerEnabled: navigator.pdfViewerEnabled,
                screenWidth: window.innerWidth,
                screenHeight: window.innerHeight,
                screenColorDepth: screen.colorDepth,
                screenPixelDepth: screen.pixelDepth,
                documentWidth: document.documentElement.clientWidth,
                documentHeight: document.documentElement.clientHeight,
                screenOrientation: screen.orientation?.type || '未知',
                devicePixelRatio: window.devicePixelRatio,
                screenAvailWidth: screen.availWidth,
                screenAvailHeight: screen.availHeight,
                deviceMemory: navigator.deviceMemory || '未知',
                cpuClass: navigator.cpuClass || '未知',
                hardwareConcurrency: navigator.hardwareConcurrency || '未知',
                maxTouchPoints: navigator.maxTouchPoints || 0,
                battery: null,
                isMobile: /Mobi|Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),
                isTablet: /(tablet|ipad|playbook|silk)|(android(?!.*mobi))/i.test(navigator.userAgent.toLowerCase()),
                isDesktop: !(/Mobi|Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)),
                isTouchDevice: ('ontouchstart' in window) || (navigator.maxTouchPoints > 0),
                isBot: /bot|crawler|spider|crawling/i.test(navigator.userAgent),
                hasWebRTC: 'RTCPeerConnection' in window,
                hasLocalStorage: 'localStorage' in window,
                hasSessionStorage: 'sessionStorage' in window,
                hasIndexedDB: 'indexedDB' in window,
                hasServiceWorker: 'serviceWorker' in navigator,
                hasWebSockets: 'WebSocket' in window,
                hasWebWorker: 'Worker' in window,
                hasSharedWorker: 'SharedWorker' in window,
                hasWebAssembly: typeof WebAssembly === 'object',
                hasWebGPU: 'gpu' in navigator,
                hasWebXR: 'xr' in navigator,
                hasWebNFC: 'NDEFReader' in window,
                hasWebUSB: 'USB' in window,
                hasWebBluetooth: 'Bluetooth' in window,
                hasWebMIDI: 'requestMIDIAccess' in navigator,
                hasWebSerial: 'serial' in navigator,
                hasWebHID: 'hid' in navigator,
                hasGeolocation: 'geolocation' in navigator,
                hasWebShare: 'share' in navigator,
                hasClipboard: 'clipboard' in navigator,
                hasWebNotification: 'Notification' in window,
                hasWebAudio: 'AudioContext' in window,
                hasWebGL: this.checkWebGL('webgl'),
                hasWebGL2: this.checkWebGL('webgl2'),
                hasCanvas: this.checkWebGL('2d')
            };

            deviceInfo.os = this.getDetailedOS();
            deviceInfo.browser = this.getDetailedBrowser();
            deviceInfo.network = this.getNetworkInfo();
            deviceInfo.battery = await this.getBatteryInfo();
            deviceInfo.memory = this.getMemoryInfo();

            return deviceInfo;
        },

        isObject(value) {
            return typeof value === 'object' && value !== null;
        },

        checkWebGL(context) {
            try {
                return !!document.createElement('canvas').getContext(context);
            } catch {
                return false;
            }
        },

        async getBatteryInfo() {
            if (navigator.getBattery) {
                try {
                    const battery = await navigator.getBattery();
                    return {
                        charging: battery.charging,
                        level: battery.level * 100 + '%',
                        chargingTime: battery.chargingTime === Infinity ? '未知' : battery.chargingTime,
                        dischargingTime: battery.dischargingTime === Infinity ? '未知' : battery.dischargingTime
                    };
                } catch {
                    return '不支持';
                }
            }
            return '不支持';
        },

        getMemoryInfo() {
            if (performance && performance.memory) {
                return {
                    jsHeapSizeLimit: this.formatBytes(performance.memory.jsHeapSizeLimit),
                    totalJSHeapSize: this.formatBytes(performance.memory.totalJSHeapSize),
                    usedJSHeapSize: this.formatBytes(performance.memory.usedJSHeapSize)
                };
            }
            return '不支持内存信息';
        },

        getNetworkInfo() {
            if (navigator.connection) {
                const conn = navigator.connection;
                return {
                    type: conn.type,
                    effectiveType: conn.effectiveType,
                    downlink: conn.downlink,
                    rtt: conn.rtt,
                    saveData: conn.saveData,
                    bandwidth: conn.bandwidth
                };
            }
            return '无网络信息';
        },

        getDetailedOS() {
            const userAgent = navigator.userAgent;
            let os = {
                name: '未知',
                version: '未知',
                architecture: navigator.platform || '未知',
                kernelVersion: '未知'
            };

            if (/Windows/.test(userAgent)) {
                os.name = 'Windows';
                os.version = this.getWindowsVersion(userAgent);
            } else if (/Mac/.test(userAgent)) {
                os.name = 'MacOS';
                const match = userAgent.match(/Mac OS X ([0-9_]+)/);
                if (match) os.version = match[1].replace(/_/g, '.');
            } else if (/Android/.test(userAgent)) {
                os.name = 'Android';
                const match = userAgent.match(/Android ([0-9.]+)/);
                if (match) os.version = match[1];
            } else if (/iPhone|iPad|iPod/.test(userAgent)) {
                os.name = 'iOS';
                const match = userAgent.match(/OS ([0-9_]+)/);
                if (match) os.version = match[1].replace(/_/g, '.');
            } else if (/Linux/.test(userAgent)) {
                os.name = 'Linux';
                os.name = this.getLinuxDistro(userAgent);
            } else if (/CrOS/.test(userAgent)) {
                os.name = 'Chrome OS';
            }

            const kernelMatch = userAgent.match(/\((.*?)\)/);
            if (kernelMatch) os.kernelVersion = kernelMatch[1];

            return os;
        },

        getWindowsVersion(userAgent) {
            if (/Windows NT 10.0/.test(userAgent)) return '10/11';
            if (/Windows NT 6.3/.test(userAgent)) return '8.1';
            if (/Windows NT 6.2/.test(userAgent)) return '8';
            if (/Windows NT 6.1/.test(userAgent)) return '7';
            if (/Windows NT 6.0/.test(userAgent)) return 'Vista';
            if (/Windows NT 5.1/.test(userAgent)) return 'XP';
            return '未知';
        },

        getLinuxDistro(userAgent) {
            if (/Ubuntu/.test(userAgent)) return 'Ubuntu';
            if (/Debian/.test(userAgent)) return 'Debian';
            if (/Fedora/.test(userAgent)) return 'Fedora';
            return 'Linux';
        },

        getDetailedBrowser() {
            const userAgent = navigator.userAgent;
            let browser = {
                name: '未知',
                version: '未知'
            };

            if (/Chrome/.test(userAgent) && /Google Inc/.test(navigator.vendor)) {
                browser.name = 'Chrome';
                const match = userAgent.match(/Chrome\/([0-9.]+)/);
                if (match) browser.version = match[1];
            } else if (/Firefox/.test(userAgent)) {
                browser.name = 'Firefox';
                const match = userAgent.match(/Firefox\/([0-9.]+)/);
                if (match) browser.version = match[1];
            } else if (/Safari/.test(userAgent) && /Apple Computer/.test(navigator.vendor)) {
                browser.name = 'Safari';
                const match = userAgent.match(/Version\/([0-9.]+)/);
                if (match) browser.version = match[1];
            } else if (/Edge/.test(userAgent)) {
                browser.name = 'Edge';
                const match = userAgent.match(/Edge\/([0-9.]+)/);
                if (match) browser.version = match[1];
            } else if (/MSIE/.test(userAgent) || /Trident/.test(userAgent)) {
                browser.name = 'Internet Explorer';
                const match = userAgent.match(/(MSIE |Trident\/)([0-9.]+)/);
                if (match) browser.version = match[2];
            }

            return browser;
        },

        formatValue(value) {
            if (value == null) return '无数据';
            if (this.isObject(value)) {
                return JSON.stringify(value, null, 2);
            }
            return typeof value === 'boolean' ? (value ? '是' : '否') : value.toString();
        },

        formatTitle(title) {
            return title.replace(/([a-z])([A-Z])/g, '$1 $2');
        },

        organizeInfo() {
            this.organizedInfo = {
                "用户代理信息": {
                    "用户代理": this.deviceInfo.userAgent,
                    "平台": this.deviceInfo.platform,
                    "语言": this.deviceInfo.language,
                    "支持的语言": this.deviceInfo.languages.join(', ')
                },
                "屏幕信息": {
                    "屏幕宽度": `${this.deviceInfo.screenWidth}px`,
                    "屏幕高度": `${this.deviceInfo.screenHeight}px`,
                    "屏幕颜色深度": `${this.deviceInfo.screenColorDepth}位`,
                    "屏幕像素深度": `${this.deviceInfo.screenPixelDepth}位`,
                    "可用屏幕宽度": `${this.deviceInfo.screenAvailWidth}px`,
                    "可用屏幕高度": `${this.deviceInfo.screenAvailHeight}px`,
                    "设备像素比": this.deviceInfo.devicePixelRatio,
                    "屏幕方向": this.deviceInfo.screenOrientation,
                },
                "硬件信息": {
                    "设备内存": `${this.deviceInfo.deviceMemory}GB`,
                    "CPU类型": this.deviceInfo.cpuClass,
                    "硬件并发数": this.deviceInfo.hardwareConcurrency,
                    "最大触摸点数": this.deviceInfo.maxTouchPoints,
                },
                "电池信息": this.deviceInfo.battery || '不支持电池信息',
                "内存信息": this.deviceInfo.memory || '不支持内存信息',
                "API支持": {
                    "WebRTC支持": this.deviceInfo.hasWebRTC ? '支持' : '不支持',
                    "WebSocket支持": this.deviceInfo.hasWebSockets ? '支持' : '不支持',
                    "WebAssembly支持": this.deviceInfo.hasWebAssembly ? '支持' : '不支持',
                    "Service Worker支持": this.deviceInfo.hasServiceWorker ? '支持' : '不支持',
                },
                "网络信息": this.deviceInfo.network || '无网络信息',
                "操作系统信息": this.deviceInfo.os,
                "浏览器信息": this.deviceInfo.browser
            };
        },

        formatBytes(bytes) {
            if (bytes === 0) return '0 B';
            const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
            const i = Math.floor(Math.log(bytes) / Math.log(1024));
            return `${(bytes / Math.pow(1024, i)).toFixed(2)} ${sizes[i]}`;
        }
    }
};
</script>

<style scoped>
.device-info {
    font-family: '微软雅黑', sans-serif;
    padding: 30px;
    background-color: #e0f7fa;
    border-radius: 10px;
    box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
}

.theme-toggle {
    margin-bottom: 25px;
    display: flex;
    justify-content: flex-start;
}

button {
    background-color: #ffffff;
    border: 1px solid #00796b;
    padding: 12px 18px;
    margin-right: 12px;
    cursor: pointer;
    border-radius: 8px;
    transition: background-color 0.3s, color 0.3s;
}

button.active {
    background-color: #00796b;
    color: white;
}

button span {
    font-size: 22px;
}

.title {
    font-size: 2.5rem;
    color: #004d40;
    margin-bottom: 25px;
}

.info-section {
    margin-bottom: 25px;
    padding: 20px;
    background-color: #ffffff;
    border-radius: 8px;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}

.section-title {
    font-size: 1.8rem;
    color: #004d40;
    margin-bottom: 12px;
}

.info-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 20px;
}

.info-item {
    display: flex;
    justify-content: space-between;
    font-size: 1.1rem;
    background-color: #f1f8e9;
    padding: 12px;
    border: 1px solid #c8e6c9;
    border-radius: 8px;
    transition: background-color 0.3s;
}

.info-item:hover {
    background-color: #c8e6c9;
}

.info-item label {
    font-weight: bold;
}
</style>
